home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / appl / napsaterm / display.c < prev    next >
C/C++ Source or Header  |  1994-05-14  |  11KB  |  527 lines

  1. RCS_ID_C "$Id: display.c,v 3.2 1994/05/11 16:48:06 ppessi Exp $";
  2. /* 
  3.  * display.c --- generic display routines for niftyterm
  4.  *
  5.  * Copyright 1989, Chris Newman
  6.  * All Rights Reserved
  7.  * Permission is granted ot copy, modify, and use this as long
  8.  * as this notice remains intact.  This is a nifty program.
  9.  *
  10.  * DISCLAIMER: the author (and maintainer) of this program is not responsible
  11.  * for any damage or other problems caused by it.
  12.  *
  13.  * $Author: ppessi $ $Revision: 3.2 $ $Date: 1994/05/11 16:48:06 $
  14.  *
  15.  */
  16.  
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <ctype.h>
  20.  
  21. #include "nifty.h"
  22. #include "display.h"
  23. #include "dispmacros.h"
  24. #include "napsaprefs.h"
  25.  
  26. /*
  27.  * display specific routines called:
  28.  * dsscroll(), dsinvert(), dsstyle(), dsputs()
  29.  * dssetfont()
  30.  */
  31.  
  32. /* global display structure */
  33. struct nifty_display disp;
  34.  
  35. /* global settings in emulate.c needed for soft reset */
  36. extern int vt100_yucky_wrap_mode;
  37.  
  38. /*
  39.  * allocate the display buffers
  40.  */
  41. void allocate_display(int width, int height)
  42. {
  43.     disp.buf = calloc((sizeof(char) * (width + 1) * height), 1);
  44.     disp.sbuf = calloc((sizeof(short) * (width + 1) * height), 1);
  45.     disp.tabstops = calloc((sizeof (char) * width), 1);
  46.     disp.maxwidth = width;
  47.     disp.maxheight = height;
  48.     disp.bufwidth = width + 1;
  49.  
  50.     if (disp.buf == NULL || disp.sbuf == NULL || disp.tabstops == NULL) {
  51.     fatalError(MEMORY_ERROR_MSG);
  52.     }
  53. }
  54.  
  55. /*
  56.  * Free up memory allocated for display 
  57.  */
  58. void free_display(void)
  59. {
  60.     if (disp.buf) 
  61.     free(disp.buf), disp.buf = NULL;
  62.     if (disp.sbuf) 
  63.     free(disp.sbuf), disp.sbuf = NULL;
  64.     if (disp.tabstops) 
  65.     free(disp.tabstops), disp.tabstops = NULL;
  66. }
  67.  
  68. /*
  69.  * clear out the display
  70.  */
  71. void clear_display(void)
  72. {
  73.     register int y;
  74.      
  75.     for (y = 0; y < disp.maxheight; y++) {
  76.     disp.plines[y] = disp.buf+y*disp.bufwidth;
  77.     disp.pstyles[y] = disp.sbuf+y*disp.bufwidth;
  78.     STYLEFLAG(y) = 0;
  79.     LINELENST(y) = 0;
  80.     }
  81.     disp.curx = disp.cury = 0;
  82. }
  83.  
  84. /*
  85.  * clear out the tab stops
  86.  */
  87. void clear_tabstops(void)
  88. {
  89.     register int i;
  90.  
  91.     for (i=0; i<disp.maxwidth; i++)
  92.     disp.tabstops[i] = 0;
  93. }
  94.  
  95. /*
  96.  * initialize tabstops to 8 characters
  97.  */
  98. void init_tabstops(void)
  99. {
  100.     register int i;
  101.  
  102.     for (i=0; i<disp.maxwidth; i++)
  103.     disp.tabstops[i] = (i % 8) == 0;
  104. }
  105.  
  106. /*
  107.  * reset the display
  108.  */
  109. void reset_display(int soft)
  110. {
  111.     if (!soft) {
  112.         clear_display();
  113.     disp.scrolldefault = 1;
  114.     }
  115.     (void) dsstyle(STYLESOFF);
  116.     disp.visual = np.visual;
  117.     disp.insert = disp.origin = disp.scrolltop = disp.savex = disp.savey = 0;
  118.     disp.scrollbot = soft ? disp.winheight - 1 : disp.maxheight;
  119.     disp.scrollskip = disp.scrolldefault;
  120.     disp.wrap = 1;
  121.     init_tabstops();
  122. }
  123.  
  124. /*
  125.  * move cursor to x, y
  126.  */
  127. void dscursorto(int x, int y)
  128. {
  129.     int    wflag;
  130.     
  131.     if (disp.origin) {
  132.     y += disp.scrolltop;
  133.     MAXBOUNDCK(y, disp.scrollbot);
  134.     } else
  135.     SLIMITCK(y, disp.winheight);
  136.     if (disp.cury != y)
  137.     dssetfont(disp.style, disp.cury = y);
  138.     wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
  139.     disp.curx = SLIMIT(x, disp.winwidth/wflag);
  140. }
  141.  
  142. /*
  143.  * return size of the current window
  144.  */
  145. void dsgetsize(int *x, int *y)
  146. {
  147.     *x = disp.winwidth;
  148.     *y = disp.winheight;
  149. }
  150.  
  151. /*
  152.  * get cursor position
  153.  */
  154. void dsgetcursor(int *x, int *y)
  155. {
  156.     *x = disp.curx;
  157.     *y = disp.cury;
  158. }
  159.  
  160. /*
  161.  * display style changes
  162.  */
  163. int dsstyle(int style)
  164. {
  165.     switch (style) {
  166.     case BOLD1: /* bold on */
  167.         disp.style |= BOLD;
  168.         break;
  169.     case BOLD0: /* bold off */
  170.         disp.style &= ~BOLD;
  171.         break;
  172.     case ITALIC1: /* italic on */
  173.         disp.style |= ITALIC;
  174.         break;
  175.     case ITALIC0: /* italic off */
  176.         disp.style &= ~ITALIC;
  177.         break;
  178.     case UNDERLINE1: /* underline on */
  179.         disp.style |= UNDERLINE;
  180.         break;
  181.     case UNDERLINE0: /* underline off */
  182.         disp.style &= ~UNDERLINE;
  183.         break;
  184.     case INVERSE1: /* inverse on */
  185.         disp.style |= INVERSE;
  186.         break;
  187.     case INVERSE0: /* inverse off */
  188.         disp.style &= ~INVERSE;
  189.         break;
  190.     case BLINK1:
  191.         disp.style |= FLASH;
  192.         break;
  193.     case BLINK0:
  194.         disp.style &= ~FLASH;
  195.         break;
  196.     case ALTERNATE1:
  197.         disp.style |= ALTERNATE;
  198.         break;
  199.     case ALTERNATE0:
  200.         disp.style &= ~ALTERNATE;
  201.         break;
  202.     case STYLESOFF: /* turn off all */
  203.         disp.style = 0;
  204.         break;
  205.     case SAVE_STYLE: /* save the style */
  206.         disp.savestyle = disp.style;
  207.         break;
  208.     case RESTORE_STYLE: /* restore the saved style */
  209.         disp.style = disp.savestyle;
  210.         break;
  211.     case DWIDTH1: /* double width */
  212.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == (DOUBLE1 | DOUBLE2))
  213.         break;
  214.         STYLEFLAG(disp.cury) |= DOUBLE1 | DOUBLE2;
  215.         redraw_line(disp.cury);
  216.         break;
  217.     case DWIDTHTOP:/* double width/height top */
  218.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE1)
  219.         break;
  220.         STYLEFLAG(disp.cury) &= ~DOUBLE2;
  221.         STYLEFLAG(disp.cury) |= DOUBLE1;
  222.         redraw_line(disp.cury);
  223.         break;
  224.     case DWIDTHBOT: /* double width/height bottom */
  225.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE2)
  226.         break;
  227.         STYLEFLAG(disp.cury) &= ~DOUBLE1;
  228.         STYLEFLAG(disp.cury) |= DOUBLE2;
  229.         redraw_line(disp.cury);
  230.         break;
  231.     case DWIDTH0: /* single width, single height */
  232.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == 0)
  233.         break;
  234.         STYLEFLAG(disp.cury) &= ~DOUBLE_MASK;
  235.         redraw_line(disp.cury);
  236.         break;
  237.     default: /* style unavailable */
  238.         return -1;
  239.     }
  240.     dssetfont(disp.style, disp.cury);
  241.  
  242.     return 0;
  243. }
  244.  
  245. /*
  246.  * check if cursor can move down without scrolling, and move cursor if it can.
  247.  */
  248. int dscheckdown(void)
  249. {
  250.     return (disp.cury < disp.scrollbot ? ++disp.cury : 0);
  251. }
  252.  
  253. /*
  254.  * move the cursor
  255.  */
  256. void dscursormove(int move, int n)
  257. {
  258.     int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
  259.  
  260.     if (n<1)  n=1;
  261.     switch (move) {
  262.     case CURSOR_UP: case REVERSE_INDEX:
  263.         disp.cury -= n;
  264.         if (disp.cury < disp.scrolltop) {
  265.         if (move == REVERSE_INDEX) {
  266.             dsscroll(disp.scrolltop,disp.scrollbot - disp.scrolltop + 1,disp.cury - disp.scrolltop);
  267.         }
  268.         disp.cury = disp.scrolltop;
  269.         }
  270.         break;
  271.         
  272.     case CURSOR_RIGHT:
  273.         disp.curx += n;
  274.         SLIMITCK(disp.curx, disp.winwidth/wflag);
  275.         break;
  276.  
  277.     case CURSOR_LEFT:
  278.         disp.curx -= n;
  279.         MINBOUNDCK(disp.curx, 0);
  280.         break;
  281.  
  282.     case DOWN1_AND_SCROLL:
  283.         {
  284.         int scrolltop = disp.scrolltop;
  285.         int scrollheight = disp.scrollbot - scrolltop;
  286.         int scrollsize;
  287.         
  288.         if (disp.scrollskip > n)
  289.             n = disp.scrollskip;
  290.         if (disp.cury > disp.scrollbot) {
  291.             scrollheight = disp.winheight;
  292.             scrolltop = 0;
  293.         }
  294.         if (n > (scrollsize = (scrollheight >> 1)))
  295.             n = scrollsize ? scrollsize : 1;
  296.         disp.cury -= n-1;
  297.         dsscroll(scrolltop, scrollheight + 1, n);
  298.         }
  299.         break;
  300.  
  301.     case CURSOR_DOWN: case NEXT_LINE: case INDEX:
  302.         if (disp.cury <= disp.scrollbot 
  303.         && (disp.cury+=n) > disp.scrollbot) {
  304.         if (move == CURSOR_DOWN) {
  305.             disp.cury = disp.scrollbot;
  306.         } else {
  307.             dsscroll(disp.scrolltop,
  308.                  disp.scrollbot - disp.scrolltop + 1,
  309.                  disp.cury - disp.scrollbot + disp.scrollskip - 1);
  310.             disp.cury = disp.scrollbot - disp.scrollskip + 1;
  311.         }
  312.         } else if (disp.cury > disp.scrollbot 
  313.                && (disp.cury+=n) > disp.winheight-1) {
  314.         if (move == CURSOR_DOWN) {
  315.             disp.cury = disp.winheight-1;
  316.         } else {
  317.             dsscroll(0, disp.winheight, 
  318.                  disp.cury - disp.winheight + disp.scrollskip);
  319.             disp.cury = disp.winheight - disp.scrollskip;
  320.         }
  321.         }
  322.         if (move != NEXT_LINE)
  323.         break;
  324.         /* fall through */
  325.     case BEGIN_LINE:
  326.         disp.curx = 0;
  327.         break;
  328.  
  329.     case END_LINE:
  330.         disp.curx = disp.winwidth/wflag-1;
  331.         break;
  332.  
  333.     case BOTTOM_HOME:
  334.         disp.curx = 0;
  335.         disp.cury = disp.winheight-1;
  336.         break;
  337.  
  338.     case SAVE_CURSOR:
  339.         disp.savex = disp.curx;
  340.         disp.savey = disp.cury;
  341.         (void) dsstyle(SAVE_STYLE);
  342.         break;
  343.  
  344.     case RESTORE_CURSOR:
  345.         disp.curx = disp.savex;
  346.         disp.cury = disp.savey;
  347.         (void) dsstyle(RESTORE_STYLE);
  348.         break;
  349.  
  350.     case INSERT_LINE:
  351.         dsscroll(disp.cury, disp.scrollbot-disp.cury+1, -n);
  352.         break;
  353.  
  354.     case DELETE_LINE:
  355.         dsscroll(disp.cury, disp.scrollbot-disp.cury+1, n);
  356.         break;
  357.  
  358.     case INSERT_CHAR: {
  359.         char insertme[MAXWIDTH];
  360.         int temp;
  361.         
  362.         disp.insert++;
  363.         insertme[SLIMIT(n,MAXWIDTH)] = '\0';
  364.         for (temp = n; --temp >= 0; insertme[temp] = ' ');
  365.         temp = disp.curx;
  366.         dsputs(insertme);
  367.         disp.curx = temp;
  368.         disp.insert--;
  369.         }
  370.         break;
  371.  
  372.     case TAB_STOP:
  373.         if (n > 1) {
  374.         while (disp.curx < disp.winwidth/wflag-1 && ++disp.curx % n);
  375.         } else {
  376.         while (disp.curx < disp.winwidth/wflag-1 &&
  377.                !disp.tabstops[++disp.curx]);
  378.         }
  379.         break;
  380.     }
  381.     dssetfont(disp.style, disp.cury);
  382. }
  383.  
  384. /*
  385.  * miscellaneous terminal functions
  386.  */
  387. void dsfunction(int what)
  388. {
  389.     int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
  390.  
  391.     switch(what) {
  392.     case ERASETO_EOS:
  393.         if (disp.cury < disp.winheight - 1)
  394.         dsclear(0, disp.cury + 1, 
  395.             disp.winwidth / wflag - 1, disp.winheight - 1);
  396.         /* fall through */
  397.     case ERASETO_EOL:
  398.         if (disp.curx < disp.winwidth/wflag-1)
  399.         dsclear(disp.curx, disp.cury, 
  400.             disp.winwidth / wflag - 1, disp.cury);
  401.         break;
  402.  
  403.     case ERASETO_SOS:
  404.         if (disp.cury)
  405.         dsclear(0, 0, disp.winwidth/wflag-1, disp.cury-1);
  406.         /* fall through */
  407.     case ERASETO_SOL:
  408.         if (disp.curx)
  409.         dsclear(0, disp.cury, disp.curx, disp.cury);
  410.         break;
  411.  
  412.     case ERASE_LINE:
  413.         dsclear(0, disp.cury, disp.winwidth/wflag-1, disp.cury);
  414.         break;
  415.  
  416.     case RESET_DISPLAY:
  417.         reset_display(1);
  418.         break;
  419.  
  420.     case SCROLL_UP:
  421.         dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, 1);
  422.         break;
  423.  
  424.     case SCROLL_DOWN:
  425.         dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, -1);
  426.         break;
  427.  
  428.     case ORIGIN_ON:
  429.         disp.origin = 1;
  430.         break;
  431.  
  432.     case ORIGIN_OFF:
  433.         disp.origin = 0;
  434.         break;
  435.  
  436.     case BLOCK_CURSOR:
  437.         disp.visual |= CUR_BLOCK;
  438.         break;
  439.  
  440.     case UNDERLINE_CURSOR:
  441.         disp.visual &= ~CUR_BLOCK;
  442.         break;
  443.  
  444.     case INVISIBLE_CURSOR:
  445.         disp.visual |= CUR_INVISIBLE;
  446.         break;
  447.  
  448.     case VISIBLE_CURSOR:
  449.         disp.visual &= ~CUR_INVISIBLE;
  450.         break;
  451.  
  452.     case WRAP_ON:
  453.         disp.wrap = 1;
  454.         break;
  455.  
  456.     case WRAP_OFF:
  457.         disp.wrap = 0;
  458.         break;
  459.  
  460.     case INSERT_ON:
  461.         disp.insert = 1;
  462.         break;
  463.  
  464.     case INSERT_OFF:
  465.         disp.insert = 0;
  466.         break;
  467.  
  468.     case SET_TAB:
  469.         disp.tabstops[disp.curx] = 1;
  470.         break;
  471.  
  472.     case CLEAR_TAB:
  473.         disp.tabstops[disp.curx] = 0;
  474.         break;
  475.  
  476.     case CLEAR_ALL_TABS:
  477.         clear_tabstops();
  478.         break;
  479.     }
  480.     dssetfont(disp.style, disp.cury);
  481. }
  482.  
  483. /*
  484.  * set the scrolling region
  485.  */
  486. void dssetscroll(int top, int bot)
  487. {
  488.     if (top)
  489.     top--;
  490.     if (bot)
  491.     bot--;
  492.     if (bot - top < 1)
  493.     disp.scrolltop = 0, disp.scrollbot = disp.winheight - 1;
  494.     else {
  495.     if (top >= disp.winheight)
  496.         top = 0;
  497.     if (bot >= disp.winheight)
  498.         bot = disp.winheight-1;
  499.     disp.scrolltop = top;
  500.     disp.scrollbot = bot;
  501.     }
  502.     disp.curx = 0;
  503.     if (disp.origin)
  504.        disp.cury = disp.scrolltop;
  505.     else
  506.        disp.cury = 0;
  507.     if (disp.scrolltop || disp.scrollbot < disp.winheight - 1)
  508.     disp.scrollskip = 1;
  509.     else
  510.     disp.scrollskip = disp.scrolldefault;
  511.     dssetfont(disp.style, disp.cury);
  512. }
  513.  
  514. /*
  515.  * Set cursor map to use
  516.  */
  517. void dskeyboard(int cmd, int val)
  518. {
  519.     switch (cmd) {
  520.     case DS_CURSORMODE: 
  521.     case DS_KEYPADAPPMODE:
  522.         np.cursormap = val;
  523.     break;
  524.     }
  525. }
  526.  
  527.